home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / uemlsrc.arc / display.c < prev    next >
C/C++ Source or Header  |  1987-08-24  |  34KB  |  991 lines

  1. /*
  2.  * The functions in this file
  3.  * handle redisplay. There are two halves,
  4.  * the ones that update the virtual display
  5.  * screen, and the ones that make the physical
  6.  * display screen the same as the virtual
  7.  * display screen. These functions use hints
  8.  * that are left in the windows by the
  9.  * commands.
  10.  */
  11. #include        <stdio.h>
  12. #include        <osbind.h>
  13. #include        "ed.h"
  14.  
  15. #define WFDEBUG 0                       /* Window flag debug.           */
  16. #define BELL    0x07
  17.  
  18. typedef struct  VIDEO {
  19.         short   v_flag;                 /* Flags                        */
  20.         char    v_text[];               /* Screen data.                 */
  21. }       VIDEO;
  22.  
  23. #define VFCHG   0x0001                  /* Changed.                     */
  24. #define VFEXT   0x0002                  /* extended (beyond column 80)  */
  25. #define VFREV   0x0004                  /* reverse ?                    */
  26. #define VFREQ   0x0008
  27. int     sgarbf  = TRUE;                 /* TRUE if screen is garbage    */
  28. int     mpresf  = FALSE;                /* TRUE if message in last line */
  29. int     vtrow   = 0;                    /* Row location of SW cursor    */
  30. int     vtcol   = 0;                    /* Column location of SW cursor */
  31. int     ttrow   = HUGE;                 /* Row location of HW cursor    */
  32. int     ttcol   = HUGE;                 /* Column location of HW cursor */
  33. int     lbound  = 0;                    /* leftmost column of current ln*/
  34. char    mlbuf[256];                     /* modeline buffer              */
  35. VIDEO   **vscreen;                      /* Virtual screen.              */
  36. VIDEO   **pscreen;                      /* Physical screen.             */
  37.  
  38. /*
  39.  * Initialize the data structures used
  40.  * by the display code. The edge vectors used
  41.  * to access the screens are set up. The operating
  42.  * system's terminal I/O channel is set up. All the
  43.  * other things get initialized at compile time.
  44.  * The original window has "WFCHG" set, so that it
  45.  * will get completely redrawn on the first
  46.  * call to "update".
  47.  */
  48. vtinit()
  49. {
  50.         register int    i;
  51.         register VIDEO  *vp;
  52.  
  53. #if ST
  54.         /* save current colors for later */
  55.         savecolor();
  56. #endif
  57.         (*term.t_open)();
  58.         vscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
  59.         if (vscreen == NULL)
  60.                 abort();
  61.         pscreen = (VIDEO **) malloc(term.t_nrow*sizeof(VIDEO *));
  62.         if (pscreen == NULL)
  63.                 abort();
  64.         for (i=0; i<term.t_nrow; ++i) {
  65.                 vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
  66.                 if (vp == NULL)
  67.                         abort();
  68.                 vp->v_flag = 0;
  69.                 vscreen[i] = vp;
  70.                 vp = (VIDEO *) malloc(sizeof(VIDEO)+term.t_ncol);
  71.                 if (vp == NULL)
  72.                         abort();
  73.                 vp->v_flag = 0;
  74.                 pscreen[i] = vp;
  75.         }
  76. }
  77.  
  78. /*
  79.  * Clean up the virtual terminal
  80.  * system, in anticipation for a return to the
  81.  * operating system. Move down to the last line and
  82.  * clear it out (the next system prompt will be
  83.  * written in the line). Shut down the channel
  84.  * to the terminal.
  85.  */
  86. vttidy()
  87. {
  88.         mlerase();
  89.         movecursor(term.t_nrow, 0);
  90.         (*term.t_eeol)();
  91.         (*term.t_close)();
  92. }
  93.  
  94. /*
  95.  * Set the virtual cursor to
  96.  * the specified row and column on the
  97.  * virtual screen. There is no checking for
  98.  * nonsense values; this might be a good
  99.  * idea during the early stages.
  100.  */
  101. vtmove(row, col)
  102. register int row, col;
  103. {
  104.         vtrow = row;
  105.         vtcol = col;
  106. }
  107.  
  108. /*
  109.  * Write a character to the
  110.  * virtual screen. The virtual row and
  111.  * column are updated. If the line is too
  112.  * long put a "$" in the last column.
  113.  * This routine only puts printing characters
  114.  * into the virtual terminal buffers.
  115.  * Only column overflow is checked.
  116.  */
  117. vtputc(c)
  118. register int    c;
  119. {
  120.         register VIDEO  *vp;
  121.  
  122.         vp = vscreen[vtrow];
  123.         if (vtcol >= term.t_ncol) {
  124.                 vtcol = (vtcol + 0x07) & ~0x07;
  125.                 vp->v_text[term.t_ncol-1] = '$';
  126.         }
  127.         else if (c == '\t') {
  128.                 do {
  129.                         vtputc(' ');
  130.                 } while ((vtcol&0x07) != 0);
  131.         } else if (c<0x20 || c==0x7F) {
  132.                 vtputc('^');
  133.                 vtputc(c ^ 0x40);
  134.         } else
  135.                 vp->v_text[vtcol++] = c;
  136. }
  137.  
  138. /*
  139.  * put a character to the virtual screen in an extended line. If we are
  140.  * not yet on left edge, don't print it yet. check for overflow on
  141.  * the right margin.
  142.  */
  143. vtpute(c)
  144. register int c;
  145. {
  146.         register VIDEO      *vp;
  147.  
  148.         vp = vscreen[vtrow];
  149.         if (vtcol >= term.t_ncol) {
  150.                 vtcol = (vtcol + 0x07) & ~0x07;
  151.                 vp->v_text[term.t_ncol - 1] = '$';
  152.         }
  153.         else if (c == '\t') {
  154.                 do {
  155.                         vtpute(' ');
  156.                 } while (((vtcol + lbound)&0x07) != 0);
  157.         }
  158.         else if (c < 0x20 || c == 0x7F) {
  159.                 vtpute('^');
  160.                 vtpute(c ^ 0x40);
  161.         }
  162.         else {
  163.                 if (vtcol >= 0)
  164.                         vp->v_text[vtcol] = c;
  165.                 ++vtcol;
  166.         }
  167. }
  168.  
  169. /*
  170.  * Erase from the end of the
  171.  * software cursor to the end of the
  172.  * line on which the software cursor is
  173.  * located.
  174.  */
  175. vteeol()
  176. {
  177.         register VIDEO  *vp;
  178.  
  179.         vp = vscreen[vtrow];
  180.         while (vtcol < term.t_ncol)
  181.                 vp->v_text[vtcol++] = ' ';
  182. }
  183.  
  184. /*
  185.  * Make sure that the display is
  186.  * right. This is a three part process. First,
  187.  * scan through all of the windows looking for dirty
  188.  * ones. Check the framing, and refresh the screen.
  189.  * Second, make sure that "currow" and "curcol" are
  190.  * correct for the current window. Third, make the
  191.  * virtual and physical screens the same.
  192.  */
  193. update()
  194. {
  195.         register LINE   *lp;
  196.         register WINDOW *wp;
  197.         register VIDEO  *vp1;
  198.         register VIDEO  *vp2;
  199.         register int    i;
  200.         register int    j;
  201.         register int    c;
  202.  
  203. #if     ST
  204.         Bconout(2,0x1b);        /* hide cursor */
  205.         Bconout(2,'f');
  206. #endif
  207.         for (i = 0; i < term.t_nrow; ++i)
  208.                 vscreen[i]->v_flag &= ~VFREQ;
  209. #if     ST
  210.         wp = wheadp;
  211.         while (wp != NULL) {
  212.                 vscreen[wp->w_toprow+wp->w_ntrows]->v_flag |= VFREQ;
  213.                 wp = wp->w_wndp;
  214.         }
  215. #endif
  216.         wp = wheadp;
  217.         while (wp != NULL) {
  218.                 /* Look at any window with update flags set on.         */
  219.                 if (wp->w_flag != 0) {
  220.                         /* If not force reframe, check the framing.     */
  221.                         if ((wp->w_flag&WFFORCE) == 0) {
  222.                                 lp = wp->w_linep;
  223.                                 for (i=0; i<wp->w_ntrows; ++i) {
  224.                                         if (lp == wp->w_dotp)
  225.                                                 goto out;
  226.                                         if (lp == wp->w_bufp->b_linep)
  227.                                                 break;
  228.                                         lp = lforw(lp);
  229.                                 }
  230.                         }
  231.                         /* Not acceptable, better compute a new value   */
  232.                         /* for the line at the top of the window. Then  */
  233.                         /* set the "WFHARD" flag to force full redraw.  */
  234.                         i = wp->w_force;
  235.                         if (i > 0) {
  236.                                 --i;
  237.                                 if (i >= wp->w_ntrows)
  238.                                         i = wp->w_ntrows-1;
  239.                         } else if (i < 0) {
  240.                                 i += wp->w_ntrows;
  241.                                 if (i < 0)
  242.                                         i = 0;
  243.                         } else
  244.                                 i = wp->w_ntrows/2;
  245.                         lp = wp->w_dotp;
  246.                         while (i!=0 && lback(lp)!=wp->w_bufp->b_linep) {
  247.                                 --i;
  248.                                 lp = lback(lp);
  249.                         }
  250.                         wp->w_linep = lp;
  251.                         wp->w_flag |= WFHARD;   /* Force full.          */
  252.